﻿//-----------------------------------------------------------------------
// <copyright file="Program.cs" company="DylanBox">
// Copyright (c) DylanBox Corporation. All rights reserved.
// </copyright>
// <summary>
//      Extension Methods,
//      LINQ
//      XSD
// </summary>
// <reference>
//      新Orcas语言特性：扩展方法 
//    http://blog.joycode.com/scottgu/archive/2007/04/07/100611.joy
// </reference>
// <author>Dylan</author>
//-----------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;

namespace SimpleLINQ
{
    public class CustomePerson
    {
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public int Age { get; set; }
    } 


    class Program
    {
        static void Main(string[] args)
        {
            /////////////////////////////////////////////
            // LINQ to object
            ////////////////////////////////////////////
            List<CustomePerson> people = new List<CustomePerson> 
            {
                new CustomePerson { FirstName = "Scott", LastName = "Guthrie", Age = 32 },
                new CustomePerson { FirstName = "Bill", LastName = "Gates", Age = 50 },
                new CustomePerson { FirstName = "Susanne", LastName = "Guthrie", Age = 32 }
            };

            IEnumerable<CustomePerson> queryObjResult;

            // 返回包含2个对象的序列，Scott 和 Susanne。
            queryObjResult = people.Where(p => p.FirstName.StartsWith("S")); // Lambda表达式 是 C# 2.0匿名方法更简明的形式
            
            // Lambda表达式其实就是匿名函数的简单写法，上面等价于
            queryObjResult = people.Where(
                                            delegate(CustomePerson p)
                                            {
                                                return p.FirstName.StartsWith("S");
                                            }
                                          );

            // query syntax, 编译器会翻译成扩展方法调用（Lambda表达式为参数）
            queryObjResult = from p in people
                             where p.FirstName.StartsWith("S")
                             orderby p.LastName
                             select p;                                            
         

            ///////////////////////////////////////////
            //LINQ to XML (notice, how to handle with xmlns)
            //////////////////////////////////////////
            XDocument document = XDocument.Load("People.xml");

            // 返回一个“XElement”元素序列，XElemen是没有类型的XML节点元素。            
            IEnumerable<XElement> queryXMLResult;
            XNamespace ns = document.Root.Name.Namespace;
            queryXMLResult = document.Descendants(ns + "person").Where(p => p.Element(ns + "firstname").Value.StartsWith("S"));

            // 通过LINQ的 Select() 扩展方法来构造数据形状，
            IEnumerable<CustomePerson> queryXMLResult2obj;
           
            queryXMLResult2obj = document.Descendants(ns + "person")
                .Where(p => p.Element(ns + "firstname").Value.StartsWith("S"))
                .Select(
                    s => new CustomePerson
                    {
                        FirstName = s.Element(ns + "firstname").Value,
                        LastName = s.Element(ns + "lastname").Value,
                        Age = Convert.ToInt32(s.Attribute("age").Value)
                    });

            // Average extension method
            double averageAge = document.Descendants(ns + "person")
                .Average(p => Convert.ToInt32(p.Attribute("age").Value));

            // Max extension method
            double maxAge = document.Descendants(ns + "person")
                .Max(p => Convert.ToInt32(p.Attribute("age").Value));


            ///////////////////////////////////////////
            //LINQ to DB
            //////////////////////////////////////////
            // LINQ2PeopleDataContext is auto-created by ORM designer(WYSIWYG)
            LINQ2PeopleDataContext peopleDb = new LINQ2PeopleDataContext();
            IEnumerable<Person> queryDBResult;
            queryDBResult = peopleDb.Persons.Where(p => p.FirstName.StartsWith("S"));
            
            averageAge = peopleDb.Persons.Average(p => p.Age);
            maxAge = peopleDb.Persons.Max(p => p.Age);  
        }
    }
}
